home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
4_0
/
GNUUCP_2
/
SOURCE
/
SYSDEP.AMI
< prev
next >
Wrap
Text File
|
1989-07-31
|
14KB
|
556 lines
/*
* @(#)sysdep.amiga 1.2 87/09/23 Copyright 1987 Free Software Foundation, Inc.
*
* Copying and use of this program are controlled by the terms of the
* GNU Emacs General Public License.
*/
#ifndef lint
char sysdep_version[] = "@(#)sysdep.amiga gnuucp Version hoptoad-1.2";
#endif
/*
* Created 23 Sept 1987 by John Gilmore, using material from sysdep.unix
* and from an older Amiga uuslave port by:
* William Loftus (burdvax!wpl), Feb 1987
*/
#include "includes.h"
#include "uucp.h"
#include "sysdep.h"
#define MULTITASK
#define STDIN 0
#define LIBDIR "/usr/lib/uucp"
#define CONTROL "/usr/lib/uucp/gnuucp.ctl"
#define PUBDIR "/usr/spool/uucppublic"
#define LOGFILE "LOGFILE"
#define O_BINARY 0 /* No distinction between text and binary */
/*
* Exported variables
*/
char sysdep_control[] = CONTROL;
/* Our variables */
/* Declarations for the serial read and write. */
extern struct MsgPort *CreatePort();
struct IOExtSer *Read_Request;
static char rs_in[2];
struct IOExtSer *Write_Request;
static char rs_out[2];
struct timerequest Timer;
struct MsgPort *Timer_Port = NULL;
void sigint(); /* Forward declaration */
/*
* Open the serial line for an incoming call.
* Argument of NULL or empty string means stdin.
*/
int
openline(ttynam, baud)
char *ttynam;
int baud;
{
int ontheline = !(ttynam && ttynam[0]); /* FIXME, this is garbage */
int c;
Read_Request =
(struct IOExtSer *)AllocMem(sizeof(*Read_Request),
MEMF_PUBLIC|MEMF_CLEAR);
Read_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
Read_Request->IOSer.io_Message.mn_ReplyPort =
CreatePort("Read_RS",0);
if(OpenDevice(SERIALNAME,NULL,Read_Request,NULL)) {
printf("Can not open serial port for read.\n");
DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
FreeMem(Read_Request,sizeof(*Read_Request));
exit(TRUE);
}
Read_Request->IOSer.io_Length = 1;
Read_Request->IOSer.io_Data = (APTR) &rs_in[0];
Write_Request =
(struct IOExtSer *)AllocMem(sizeof(*Write_Request),
MEMF_PUBLIC|MEMF_CLEAR);
Write_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
Write_Request->IOSer.io_Message.mn_ReplyPort =
CreatePort("Write_RS",0);
if(OpenDevice(SERIALNAME,NULL,Write_Request,NULL)) {
printf("Can not open open serial port for write.\n");
DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
FreeMem(Write_Request,sizeof(*Write_Request));
DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
FreeMem(Read_Request,sizeof(*Read_Request));
exit(TRUE);
}
Write_Request->IOSer.io_Command = CMD_WRITE;
Write_Request->IOSer.io_Length = 1;
Write_Request->IOSer.io_Data = (APTR) &rs_out[0];
Read_Request->io_SerFlags = 0L;
Read_Request->io_Baud = baud;
Read_Request->io_ReadLen = 8L;
Read_Request->io_WriteLen = 8L;
Read_Request->io_CtlChar = 0x11130000L;
Read_Request->io_BrkTime = 750000;
Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
DoIO(Read_Request);
Read_Request->IOSer.io_Command = CMD_READ;
Timer_Port = CreatePort("Timer Port",0L);
if (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Timer, 0)) {
printf("Can't open timer device.");
DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
FreeMem(Write_Request,sizeof(*Write_Request));
DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
FreeMem(Read_Request,sizeof(*Read_Request));
exit(TRUE);
}
Timer.tr_node.io_Message.mn_ReplyPort = Timer_Port;
Timer.tr_node.io_Command = TR_ADDREQUEST;
Timer.tr_node.io_Flags = 0;
Timer.tr_node.io_Error = 0;
BeginIO(Read_Request);
xwrite(msgo6,sizeof(msgo6)-1); /* set up terminal */
signal(SIGINT,sigint);
begin_again:
printf("Start again!!\n");
c = xgetc();
while (c == EOF) { c = xgetc(); printf(".");} /* wait for input */
printf("\nHey what was that?\n");
printf("Got %c\n %d %d %c",c,c,c & 0xFF,c & 0xFF);
/* now we have something !! */
/* Not nice, but fast! */
if ((c) == 'C') {
c = xgetc();
printf("C got %c\n",c);
if ((c) == 'O') {
c = xgetc();
printf("CO got %c\n",c);
if ((c) == 'N') {
c = xgetc();
if ((c) == 'N') {
c = xgetc();
if ((c) == 'E') {
c = xgetc();
if ((c) == 'C') {
c = xgetc();
if ((c) == 'T') {
c = xgetc();
if ((c) == ' ') {
c = xgetc();
if ((c) == '1') {
c = xgetc();
if ((c) == '2') {
c = xgetc();
if ((c) == '0') {
c = xgetc();
if ((c) == '0') {
c = xgetc();
if ((c) == '\r') {
DEBUG(1,"Someone is rapping, rapping at my ...\n", 0);
/* do it !!! */
c = xgetc();
while (c != EOF) c = xgetc(); /* zap trash*/
return;
} else goto begin_again;
} else goto begin_again;
} else goto begin_again;
} else goto begin_again;
} else goto begin_again;
} else goto begin_again;
} else goto begin_again;
} else goto begin_again;
} else goto begin_again;
} else goto begin_again;
} else goto begin_again;
} else goto begin_again;
} else goto begin_again;
}
/*
* Open the serial line for an outgoing call.
*/
int
openout(ttynam, baud)
char *ttynam;
int baud;
{
abort(); / FIXME -- write for amiga */
signal(SIGINT,sigint);
return SUCCESS;
}
/*
* Basement level I/O routines
*
* xwrite() writes a character string to the serial port
* xgetc() returns a character from the serial port, or an EOF for timeout.
* sigint() restores the state of the serial port on exit.
* hangup() hangs up the serial port (e.g. drop DTR).
*/
int
xgetc()
{
int rd,ch;
/* printf("\nxgetc\n"); */
Timer.tr_time.tv_secs = BYTE_TIMEOUT;
Timer.tr_time.tv_micro = 0;
SendIO((char *) &Timer.tr_node);
/* BeginIO((char *) &Timer.tr_node);*/
rd = FALSE;
while (rd == FALSE)
{
Wait((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) |
( 1L << Timer_Port->mp_SigBit));
if (CheckIO(Read_Request)) {
WaitIO(Read_Request);
ch=rs_in[0];
rd = TRUE;
SendIO(Read_Request);
}
if (rd == FALSE && CheckIO((char*) &Timer)) {
WaitIO((char*)&Timer);
/*printf("TIMEOUT\n");*/
return(EOF); /* Time out!!! */
}
} /* end while */
/* printf("Before AbortIO & Wait \n"); */
if (!CheckIO((char *) &Timer))
AbortIO((char *) &Timer);
else
WaitIO((char *) &Timer);
/* Wait (1L << Timer_Port->mp_SigBit); */
/* printf(" Returning '%c'\n",ch & 0xFF); */
return(ch);
}
int
xwrite(buf,ctr)
char *buf;
int ctr;
{
int i;
for (i=0; i < ctr; i++) {
rs_out[0] = (*buf++) & 0xFF;
DoIO(Write_Request);
}
return 1;
}
sigint()
{
CloseDevice(Write_Request);
DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
FreeMem(Write_Request,sizeof(*Write_Request));
CloseDevice(Read_Request);
DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
FreeMem(Read_Request,sizeof(*Read_Request));
DeletePort(Timer_Port);
printf("User requested termination.\n");
exit(TRUE);
}
/*
* hangup(): hang up the 'fone.
*/
int
hangup()
{
abort(); /* FIXME -- write for Amiga */
sleep(2); /* To be sure DTR stays down that long */
}
/*
* Create a temporary file name for receiving a file into.
* "name" is the name we will actually eventually want to use for the file.
* We currently ignore it, but some OS's that can't move files around
* easily might want to e.g. put the temp file into the same directory
* that this file is going into.
*
* FIXME:
* This interface should be able to return a "possible" filename, and
* be re-called if the name is already in use, to get another.
* This avoids checking here whether the name is good -- saving system calls.
*/
char *
temp_filename(name)
register char *name;
{
static char tname[NAMESIZE];
if (ourpid == 0)
ourpid = getpid();
(void) sprintf(tname, "TM.u%d", ourpid);
DEBUG(7, "Using temp file %s\n", tname);
return tname;
}
/*
* Transform a filename from a uucp packet (in Unix format) into a local
* filename that will work in the local file system.
*/
char *
munge_filename(name)
register char *name;
{
register char *p;
static char buffer[NAMESIZE+SLOP];
int len, hostlen;
DEBUG(7, "Munge_filename input: %s\n", name);
/* FIXME: Security checking goes here! */
if (name[0] == '~') {
/* Handle user-relative names -- ~ or ~uucp turns to PUBDIR */
if (name[1] == '/')
p = &name[1];
else if (!strncmp("~uucp/", name, 6))
p = &name[5];
else {
p = NULL; /* Neither of the above */
goto out;
}
strcpy(buffer, PUBDIR);
strcat(buffer, p);
p = buffer;
goto out;
}
#ifdef SUBDIR
/* Berkeley Unix subdirectory hack.
* Full pathnames go through OK.
* D.myname* -> D.myname/D.myname*
* D.* -> D./D.*
* C.* -> C./C.*
* otherwise left alone (e.g. X.*, LCK.*, STST.*).
* FIXME: I hear Honey Danber has a slightly different scheme.
* In particular, STST's go in a directory.
*/
if (name[0] != '/') {
if (name[1] == '.' &&
(name[0] == 'C' || name[0] == 'D')) {
len = strlen(name);
hostlen = strlen(Myname);
if (hostlen > 7) hostlen = 7;
/* Check D.mynameAxxxx case */
if (name[0] == 'D' && len == hostlen + 2 + 5 &&
!strncmp(&name[2], Myname, hostlen))
len = 2 + hostlen; /* "D."+name */
else
len = 2; /* Just "D." */
strcpy(buffer, name);
buffer[len] = '/';
strcpy(buffer+len+1, name);
p = buffer;
goto out;
}
}
#endif
p = name; /* Let it through as-is. */
out:
DEBUG(7, "Munge_filename output: %s\n", p);
return p;
}
/*
* Uucp work queue scan.
*
* gotsome = work_scan(hostname, type);
* workfile = work_next();
* void work_done();
*/
/*
* Local variables of the work queue scanner -- not visible to outsiders
*
* Workhost and worktype are always null-terminated; keeping their lengths
* is just a performance hack. Workprefix is NOT null terminated; various
* people copy things after it and use the whole string. Workprefix is
* exactly workplen long; to append something, strcpy(workprefix+workplen, ...)
*/
#define MAX_TYPE 10
static DIR *workdir = (DIR *)NULL;
static struct dirent *workfile;
static char workhost[MAX_HOST+1];
static int workhlen;
static char worktype[MAX_TYPE+1];
static int worktlen;
static char workfirst = 0;
/* FIXME, at the moment this can be local to work_scan() */
static char workprefix[MAX_TYPE+1+MAX_HOST+1+MAX_TYPE+1+MAX_HOST+6+SLOP];
/* D . hoptoad / D . hoptoad N1234\0 */
static int workplen;
void
work_done()
{
if (workdir)
closedir(workdir);
workdir = (DIR *) NULL;
workfile = (struct dirent *) NULL;
workfirst = 0;
}
int
work_scan(host, type)
char *host;
char *type;
{
char *p;
if (!host)
host = "";
/* If called twice in a row, don't thrash the disk again */
if (strcmp(workhost, host) == SAME &&
strcmp(worktype, type) == SAME && workfile)
return 1;
if (workdir) work_done(); /* Clean up prev call */
workfirst = 1; /* Initialize for work_next */
workhlen = strlen(host);
if (workhlen > sizeof (workhost) -1) abort();
strcpy(workhost, host);
if (workhlen > 7) workhlen = 7; /* Unix uucp limit */
worktlen = strlen(type);
if (worktlen > sizeof (worktype) -1) abort();
strcpy(worktype, type);
/* Figure out which subdirectory this class of files is in. */
/* FIXME: doesn't handle "all D. files" since D.myname is separate. */
sprintf(workprefix, "%s.%s", worktype, workhost);
p = munge_filename(workprefix);
strcpy(workprefix, p);
p = index(workprefix, '/');
if (p)
workplen = 1 + p - workprefix; /* Prefix ends after '/' */
else
workplen = 0; /* No / in munged; hence no dir */
workprefix[workplen] = '\0';
DEBUG(7, "Work prefix is =%s=\n", workprefix);
strcpy(workprefix+workplen, ".");
workdir = opendir(workprefix); /* Open whatever directory */
if (workdir == NULL) {
DEBUG(0, "Can't open queue directory %s\n", workprefix);
return 0; /* No work */
}
return work_look();
}
static int
work_look()
{
int len;
for (;;) {
workfile = readdir(workdir);
if (workfile == NULL) {
DEBUG(7, "work_look readdir null\n", 0);
work_done();
return 0; /* No work */
}
DEBUG(7, "work_look readdir %s\n", workfile->d_name);
/* Is it the right type? */
if (strncmp(workfile->d_name, worktype, worktlen) == SAME
&& workfile->d_name[worktlen] == '.') {
/* see if it matches the hostname */
len = strlen(workfile->d_name);
/* "C" "." "hoptoad" "Xnnnn" */
if (workhlen == 0 ||
(len == worktlen + 1 + workhlen + 5 &&
!strncmp(workhost, workfile->d_name+2, workhlen))
) {
/* Found an entry! */
/* FIXME, check grade letter! */
DEBUG(7, "work_look found it!\n", 0);
return 1; /* Found work */
}
}
}
/* NOTREACHED */
}
char *
work_next()
{
if (!workfirst) {
if (!workfile || !work_look())
return (char *)NULL;
}
workfirst = 0;
return workfile->d_name;
}
/*
* Routine to return a string that gives the current date and time, and
* identifies the current process, if on a multiprocess system.
*/
char *
time_and_pid()
{
long clock;
struct tm *tm;
static int ourpid = 0;
static char format[] = "%d/%d-%d:%02d:%02d-%d";
static char outbuf[sizeof(format)];
(void) time(&clock);
tm = localtime(&clock);
if (ourpid == 0)
ourpid = getpid();
sprintf(outbuf, format,
tm->tm_mon+1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec,
ourpid);
return outbuf;
}